package com.infinitus.activity.util;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * @create: 2019/1/9
 * @desc:
 */
public class DateUtil {
    private static String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    private static String DATE_FORMAT = "yyyy-MM-dd";
    private static String DATE_FORMAT_2 = "yyyy/MM/dd";
    private static String DATE_FORMAT_3 = "yyyyMMdd";
    private static String MONTH_FORMAT = "yyyy-MM";
    private static String YEAR_FORMAT = "yyyy";
    private static String DATE_FORMAT_ZH = "yyyy年-MM月-dd日";
    //一分钟单位
    public static int AMINUTE = 60 * 1000;
    //一小时单位
    public static int AHOUR = 60 * AMINUTE;
    //一天单位
    public static int ADAY = 24 * AHOUR;
    //一周单位
    public static int AWEEK = 7 * ADAY;

    private static Date start;

    private static Date end;

    private Date startLocal;

    private Date endLocal;

    private static SimpleDateFormat dformat = new SimpleDateFormat("yyyyDD");
    private static final long dayMillin = 86400000;

    /**
     * 将日期类型转换为格式"yyyy-MM-dd HH:mm:ss"的字符串
     */
    public static String format2yyyyMMddHHmmss(Date d) {
        return new SimpleDateFormat(DATETIME_FORMAT).format(d);
    }

    /**
     * 将日期类型转换为格式"yyyy年-MM月-dd日"的字符串
     */
    public static String format2yyyyMMddZH(Date d) {
        return new SimpleDateFormat(DATE_FORMAT_ZH).format(d);
    }

    /**
     * 将日期类型转换为格式"yyyy-MM-dd"的字符串
     */
    public static String format2yyyyMMdd(Date d) {
        return new SimpleDateFormat(DATE_FORMAT).format(d);
    }


    /**
     * 将日期类型转换为格式"yyyy/MM/dd"的字符串
     */
    public static String format2yyyy1MM1dd(Date d) {
        return new SimpleDateFormat(DATE_FORMAT_2).format(d);
    }

    /**
     * 将日期类型转换为格式"yyyyMMdd"的字符串
     */
    public static String format3yyyy1MM1dd(Date d) {
        return new SimpleDateFormat(DATE_FORMAT_3).format(d);
    }

    /**
     * 将日期类型转换为格式"yyyy-MM"的字符串
     */
    public static String format2yyyyMM(Date d) {
        return new SimpleDateFormat(MONTH_FORMAT).format(d);
    }

    /**
     * 将日期类型转换为格式"yyyy"的字符串
     */
    public static String formatYear(Date d) {
        return new SimpleDateFormat(YEAR_FORMAT).format(d);
    }

    /**
     * 将字符串类型转换为日期格式"yyyy-MM-dd HH:mm:ss"
     *
     * @param str
     * @return
     */
    public static Date parse2yyyyMMddHHmmss(String str) {
        try {
            return new SimpleDateFormat(DATETIME_FORMAT).parse(str);
        } catch (ParseException e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 将字符串类型转换为日期格式"yyyy-MM-dd"
     *
     * @param str
     * @return
     */
    public static Date parse2yyyyMMdd(String str) {
        try {
            return new SimpleDateFormat(DATE_FORMAT).parse(str);
        } catch (ParseException e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 根据年月返回天数
     *
     * @param year
     * @param month
     * @return
     */
    public static int getActualDays(int year, int month) {
        GregorianCalendar currentDay = new GregorianCalendar();

        int days = 31;
        if (month == 4 || month == 6 || month == 9 || month == 11) {
            days = 30;
        }
        if (month == 2) {
            if (currentDay.isLeapYear(year)) {
                days = 29;
            } else {
                days = 28;
            }
        }
        return days;
    }

    /**
     * 返回当前日期
     *
     * @return
     */
    public static Date now() {
        return new Date();
    }

    /**
     * 取得某年中某一个月的最大天数
     *
     * @param year
     *            年
     * @param month
     *            月
     */

    public static int getMaxDay(int year, int month) {
        Calendar thisMonth = Calendar.getInstance();
        thisMonth.set(Calendar.MONTH, month - 1);
        thisMonth.set(Calendar.YEAR, year);
        thisMonth.set(Calendar.DAY_OF_MONTH, 1);
        return thisMonth.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * 根据年月日，若日超出了最大范围，则返回当月的最大天数
     *
     * @param year
     *            年
     * @param month
     *            月
     * @param day
     *            日
     * @return
     */
    public static int getDay(int year, int month, int day) {
        if (day > getMaxDay(year, month)) {
            day = getMaxDay(year, month);
        }
        return day;
    }

    /**
     * 获取day参数的下一天
     *
     * @param year
     *            年
     * @param month
     *            月
     * @param day
     *            日
     * @return
     */
    public static int[] getNextDay(int year, int month, int day) {
        int monthDay[] = new int[] { month, day, year };
        if (day > getMaxDay(year, month)) {
            monthDay[1] = 1;
            if (month == 12) {
                monthDay[0] = 1;
                monthDay[2] = year + 1;
            }
        }
        return monthDay;
    }

    /**
     * 由时间生成id
     *
     * @return
     */
    public static long getIdByTime() {
        Calendar c = Calendar.getInstance();
        long i = c.getTimeInMillis() * 100;
        int a = (int) (Math.random() * 100);
        int b = (int) (Math.random() * 10);
        return i + a + b;
    }

    /**
     * 与当前时间比较大小
     *
     * @param date
     *            指定的日期 yyyy-MM-dd HH:mm:ss
     * @return boolean
     */

    public static boolean judgeCurrentTime(Date date) {
        Long currentTime = System.currentTimeMillis();
        Long targetTime = date.getTime();
        return targetTime >= currentTime;
    }

    /**
     * 判断指定的日期是否为当天日期
     *
     * @param date
     *            指定的日期
     * @return boolean
     */

    public static boolean judgeDate(Date date) {
        GregorianCalendar currentDay = new GregorianCalendar();
        int tmpDate = currentDay.get(Calendar.DAY_OF_YEAR);
        String datePart = "";
        if (tmpDate < 10) {
            datePart = "0" + tmpDate;
        } else {
            datePart = tmpDate + "";
        }
        String currentYMonth = currentDay.get(Calendar.YEAR) + "" + datePart;
        String giveYMonth = dformat.format(date);
        if (currentYMonth.trim().equals(giveYMonth))
            return true;
        return false;
    }

    /**
     * 对两个的日期除去年月日后，时间之间的比较
     *
     * @param alarmTimeate
     *            日程提醒时间
     * @param endTime
     *            日程结束时间
     * @return boolean
     */

    public static boolean judgeDate(Date alarmTime, Date endTime) {

        return (alarmTime.getTime() + 28800000) % dayMillin <= (endTime
                .getTime() + 28800000)
                % dayMillin;
    }

    /**
     * * setStart��setEnd�ֱ��û����ʱ�ͽ����ʱ
     *
     */
    public static void setEnd() {
        setEnd(null);
    }

    public static void setEnd(String s) {
        if (start == null) {
            return;
        }
        end = new Date();
        long mSencond = end.getTime() - start.getTime();
        long second = mSencond / 1000;
        long minute = second >= 60 ? second / 60 : 0;
        second = second % 60;
        String ms = minute > 0 ? minute + "��" : "";
    }

    public static void setStart() {
        setStart(null);
    }

    public static void setStart(String s) {
        start = new Date();
    }

    public void setEndLocal() {
        setEndLocal(null);
    }

    public void setEndLocal(String s) {
        if (startLocal == null) {
            return;
        }
        endLocal = new Date();
        long mSencond = endLocal.getTime() - startLocal.getTime();
        long second = mSencond / 1000;
        long minute = second >= 60 ? second / 60 : 0;
        second = second % 60;
        String ms = minute > 0 ? minute + "��" : "";
    }

    public void setStartLocal() {
        setStartLocal(null);
    }

    public void setStartLocal(String s) {
        startLocal = new Date();
    }

    /**
     * �������
     *
     * @param date
     *            ����
     * @return �������
     */
    public static int getYear(Date date) {
        java.util.Calendar c = java.util.Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.YEAR);
    }

    /**
     * �����·�
     *
     * @param date
     *            ����
     * @return �����·�
     */
    public static int getMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.MONTH) + 1;
    }

    /**
     * �����շ�
     *
     * @param date
     *            ����
     * @return ������
     */
    public static int getDay(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * ����Сʱ
     *
     * @param date
     *            ����
     * @return ����Сʱ
     */
    public static int getHour(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * ���ط���
     *
     * @param date
     *            ����
     * @return ���ط���
     */
    public static int getMinute(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.MINUTE);
    }

    /**
     * ��������
     *
     * @param date
     *            ����
     * @return ��������
     */
    public static int getSecond(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.SECOND);
    }

    /**
     * ���غ���
     *
     * @param date
     *            ����
     * @return ���غ���
     */
    public static long getMillis(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.getTimeInMillis();
    }

    /**
     * �����ڵõ��ƶ��ĸ�ʽ�ַ�
     *
     * @param date
     * @param format
     * @return
     */
    public static String format(java.util.Date date, String format) {
        String result = null;
        if (date != null) {
            java.text.DateFormat df = new java.text.SimpleDateFormat(format);
            result = df.format(date);
        }
        return result;
    }

    /**
     * ��ȡ��ǰʱ��������µĽ��졣
     *
     * @param number
     *            ��������Ϊ�����ʾǰ������
     * @return
     */
    public static Date getNextMonth(int number) {
        Calendar ca = Calendar.getInstance();
        ca.add(Calendar.MONTH, number);
        return ca.getTime();
    }

    /**
     * ��ȡ��ǰʱ��������µĽ��졣
     *
     * @param number
     *            ��������Ϊ�����ʾǰ������
     * @param d
     *
     * @return
     */
    public static Date getNextMonth(Date d, int number) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(d);
        ca.add(Calendar.MONTH, number);
        return ca.getTime();
    }

    /**
     * ��ȡ��ǰʱ����¼����������
     *
     * @param number
     *            ��������Ϊ�����ʾǰ����
     * @return
     */
    public static Date getNextDay(int number) {
        Calendar ca = Calendar.getInstance();
        ca.add(Calendar.DATE, number);
        return ca.getTime();
    }

    /**
     * 获得给定时间的前后几天
     * @param date
     * @param number
     * @return
     */
    public static Date getNextDay(Date date, int number) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.DATE, number);
        return ca.getTime();
    }

    /**
     * 获得当前时间的相差几个小时的时间
     * @param number
     * @return
     */
    public static Date getNextHour(int number) {
        Calendar ca = Calendar.getInstance();
        ca.add(Calendar.HOUR, number);
        return ca.getTime();
    }

    /**
     * ��ȡ��ǰʱ����¼���Сʱ
     *
     * @param number
     *            ��������Ϊ�����ʾǰ����Сʱ
     * @param date
     *
     * @return
     */
    public static Date getNextHour(Date date, int number) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.HOUR, number);
        return ca.getTime();
    }

    public static Date getNextMin(int number) {
        Calendar ca = Calendar.getInstance();
        ca.add(Calendar.MINUTE, number);
        return ca.getTime();
    }

    public static Date getNextMin(Date date, int number) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.MINUTE, number);
        return ca.getTime();
    }

    /**
     * ��ǰʱ����ַ�����
     *
     * @return
     */
    public static String getDateSeries() {
        return DateUtil.format(new Date(), "yyyyMMddHHmmss");
    }

    /**
     * ʱ����ַ�����
     *
     * @return
     */
    public static String getDateSeries(Date d) {
        return DateUtil.format(d, "yyyyMMddHHmmss");
    }

    /**
     * ����֮�󼸸�Сʱ֮��ļ�����֮��ļ���֮��
     *
     * @param laterDay
     * @param theHour
     * @return
     */
    public static Date getNextDate(int laterDay, int theHour, int theMinute,
                                   int theSecond) {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, laterDay);
        c.add(Calendar.HOUR, theHour);
        c.add(Calendar.MINUTE, theMinute);
        c.add(Calendar.SECOND, theSecond);
        Date d = c.getTime();
        return d;
    }

    /**
     * ���ַ�ת��Ϊ��������
     */
    public static Date getYYYYMMDD(String str) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = null;
        try {
            dt = sdf.parse(str);
        } catch (ParseException e) {
        }
        return dt;
    }

    /**
     * ���ַ�ת��Ϊ��������
     */
    public static Date getYYYYMMDDHHMMSS(String str) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date dt = null;
        try {
            dt = sdf.parse(str);
        } catch (ParseException e) {
        }
        return dt;
    }

    /**
     * ȡ��}������֮���������
     *
     * @param larger
     * @param smaller
     * @return
     */
    public static int getDistanceDay(Date larger, Date smaller) {
        long distance = larger.getTime() - smaller.getTime();
        return (int) (distance / ADAY);
    }

    public static int getDistanceMin(Date larger, Date smaller) {
        long distance = larger.getTime() - smaller.getTime();
        return (int) (distance / AMINUTE);
    }

    public static long getDistanceSec(Date larger, Date smaller) {
        return (larger.getTime() - smaller.getTime()) / 1000;
    }

    /**
     * ȡ��}������֮���Сʱ���
     *
     * @param larger
     * @param smaller
     * @return
     */
    public static int getHourDistance(Date larger, Date smaller) {
        long distance = larger.getTime() - smaller.getTime();
        return (int) (distance / AHOUR);
    }

    /**
     * ����һ���(ʱ������ڵ�ʱ�������ַ���2008-08-08 08:08:08
     *
     * @return 2008-08-08 08:08:08
     */
    public static String getYYYYMMDDHHMMSS() {
        return getYYYYMMDDHHMMSS(new Date());
    }

    /**
     * ����һ���(ʱ������ڵ�ʱ�������ַ���2008-08-08 08:08:08
     *
     * @return 2008-08-08 08:08:08
     */
    public static String getYYYYMMDDHHMMSS(Date date) {
        String dateTime = new Timestamp(date.getTime()).toString().substring(0,
                19);
        return dateTime;
    }

    /**
     *
     * @param date
     * @return
     */
    public static String getYYYYMMDDHH(Date date) {
        String dateTime = new Timestamp(date.getTime()).toString().substring(0,
                13);
        return dateTime;
    }

    public static String getYYYYMMDDHH() {
        return getYYYYMMDDHH(new Date());
    }

    /**
     * ��ȡ��ǰʱ��
     *
     * @return
     */
    public static Date getNow() {
        return new Date();
    }

    /**
     *
     * @param date
     * @return
     */
    public static String getYYYYMMDDHHMM(Date date) {
        String dateTime = new Timestamp(date.getTime()).toString().substring(0,
                16);
        return dateTime;
    }

    public static String getYYYYMMDDHHMM(long l) {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(l);
        return getYYYYMMDDHHMM(c.getTime());
    }

    public static String getYYYYMMDDHHMM() {
        return getYYYYMMDDHHMM(new Date());
    }

    /**
     * ����һ���(ʱ�������(����)��ʱ�������ַ���2008-08-08 08:08:08
     *
     * @param date
     * @return
     */
    public static String getYYYYMMDDHHMMSSMS() {
        return getYYYYMMDDHHMMSSMS(new Date());
    }

    /**
     * ����һ���(ʱ�������(����)��ʱ�������ַ���2008-08-08 08:08:08
     *
     * @param date
     * @return
     */
    public static String getYYYYMMDDHHMMSSMS(Date date) {
        String dateTime = new Timestamp(date.getTime()).toString().substring(0,
                21);
        return dateTime;
    }

    /**
     * ��ȡһ�����ڣ�����(ʱ�䣬�磺2008-8-8
     *
     * @return 2008-8-8 �����String
     */
    public static String getYYYYMMDD() {
        Date date = new Date();
        return getYYYYMMDD(date);
    }

    /**
     * ��һ��java.util.Date���͵����ת����һ����������2008-8-8�ַ����ݡ�
     *
     * @param date
     * @return 2008-8-8
     */
    public static String getYYYYMMDD(Date date) {
        String date0 = new Timestamp(date.getTime()).toString();
        String dateString = date0.substring(0, 4) + date0.substring(5, 7)
                + date0.substring(8, 10);
        return dateString;
    }

    /**
     * ��ȡһ����2008
     *
     * @param d
     * @return 2008
     */
    public static String getYYYY(Date d) {
        return new Timestamp(d.getTime()).toString().substring(0, 4);
    }

    /**
     * ��ȡһ������05-03
     *
     * @param d
     * @return 05-03
     */
    public static String getMMDD(Date d) {
        return new Timestamp(d.getTime()).toString().substring(5, 10);
    }

    /** 获取给定时间所在周的第一天(Sunday)的日期和最后一天(Saturday)的日期
     * (周一到周日)
     *  @param calendar
     *  @return Date数组，[0]为第一天的日期，[1]最后一天的日期
     */
    public static Date[] getWeekStartAndEndDate(Calendar calendar) {
        Date[] dates = new Date[2];
        Date firstDateOfWeek, lastDateOfWeek; // 得到当天是这周的第几天
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); // 减去dayOfWeek,得到第一天的日期，因为Calendar用0－6代表一周七天，所以要减二
        calendar.add(Calendar.DAY_OF_WEEK, -(dayOfWeek - 2));
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        firstDateOfWeek = calendar.getTime(); // 每周7天，加6，得到最后一天的日子
        calendar.add(Calendar.DAY_OF_WEEK, 6);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        lastDateOfWeek = calendar.getTime();
        dates[0] = firstDateOfWeek;
        dates[1] = lastDateOfWeek;
        return dates;
    }
    /** 获取给定时间所在月的第一天F的日期和最后一天的日期
     * @param calendar
     * @return Date数组，[0]为第一天的日期，[1]最后一天的日期
     */
    public static Date[] getMonthStartAndEndDate(Calendar calendar) {
        Date[] dates = new Date[2];
        Date firstDateOfMonth, lastDateOfMonth; // 得到当天是这月的第几天
        int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH); // 减去dayOfMonth,得到第一天的日期，因为Calendar用0代表每月的第一天，所以要减一
        calendar.add(Calendar.DAY_OF_MONTH, -(dayOfMonth - 1));
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        firstDateOfMonth = calendar.getTime(); // calendar.getActualMaximum(Calendar.DAY_OF_MONTH)得到这个月有几天
        calendar.add(Calendar.DAY_OF_MONTH, calendar .getActualMaximum(Calendar.DAY_OF_MONTH) - 1);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        lastDateOfMonth = calendar.getTime();
        dates[0] = firstDateOfMonth;
        dates[1] = lastDateOfMonth;
        return dates;
    }
    /**
     * 测试
     *
     * @param args
     */
    public static void main(String[] args) {
        //System.out.println(getActualDays(2007, 2));
        //System.out.println(DateUtil.getDay(2009, 10, 45));
        //System.out.println(DateUtil.getDay(2009, 10, 45));
        Calendar now = Calendar.getInstance();
        Date[] weekDates = getWeekStartAndEndDate(now);
        Date[] monthDates = getMonthStartAndEndDate(now);
        Date date = getNextHour(-24);
        System.out.println("firstDateOfWeek: " + weekDates[0]+ " ,lastDateOfWeek: " + weekDates[1]);
        System.out.println("firstDateOfMonth: " + monthDates[0]+ " ,lastDateOfMonth: " + monthDates[1]);
        System.out.println("date:"+date);

    }
}